package com.xc.erp.modules.erp.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xc.erp.common.utils.JwtUtil;
import com.xc.erp.common.utils.RedisCache;
import com.xc.erp.common.utils.StringUtils;
import com.xc.erp.modules.erp.domain.AjaxResult;
import com.xc.erp.modules.erp.domain.dto.LoginBody;
import com.xc.erp.modules.erp.domain.dto.LoginUser;
import com.xc.erp.modules.erp.domain.pojo.JshTenant;
import com.xc.erp.modules.erp.domain.pojo.JshUser;
import com.xc.erp.modules.erp.domain.pojo.JshUserRole;
import com.xc.erp.modules.erp.mapper.JshUserMapper;
import com.xc.erp.modules.erp.mapper.JshUserRoleMapper;
import com.xc.erp.modules.erp.service.JshTenantService;
import com.xc.erp.modules.erp.service.JshUserRoleService;
import com.xc.erp.modules.erp.service.JshUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
* @author Administrator
* @description 针对表【jsh_user(用户表)】的数据库操作Service实现
* @createDate 2022-12-10 15:54:06
*/
@Service
public class JshUserServiceImpl extends ServiceImpl<JshUserMapper, JshUser>
    implements JshUserService {
    @Autowired
    private RedisCache redisCache;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private JshUserMapper jshUserMapper;

    @Autowired
    private JshUserRoleMapper jshUserRoleMapper;

    @Autowired
    private JshTenantService jshTenantService;

    @Override
    public IPage<JshUser> findByPage(Page<JshUser> page, QueryWrapper<JshUser> queryWrapper) {
        return jshUserMapper.findByPage(page, queryWrapper);
    }

    @Override
    public Page<JshUser> getUserList(Integer pageNum, Integer pageSize, String loginName, String username) {
        Page<JshUser> jshUserPage = new Page<>(pageNum, pageSize);
        QueryWrapper<JshUser> queryWrapper = new QueryWrapper<>();
        if (loginName!=null && !loginName.equals("")){
            queryWrapper.like("login_name",loginName);
        }
        if (username!=null&&!username.equals("")){
            queryWrapper.like("username",username);
        }
        Page<JshUser> page = this.baseMapper.selectPage(jshUserPage, queryWrapper);
        return page;
    }

    @Override
    public void batchSetStatus(Long[] ids, Byte status) {
        List<JshUser> userList = new ArrayList<>();
        for (int i = 0; i < ids.length; i++) {
            JshUser user = new JshUser();
            user.setStatus(status);
            user.setId(ids[i]);
            userList.add(user);
        }
        //批量操作
        this.updateBatchById(userList);
    }

    @Override
    public boolean checkIsLoginNameExist(Long id,String loginName) {
        QueryWrapper<JshUser> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(loginName)) {
            queryWrapper.eq("login_name", loginName);
        }
        JshUser jshUser = baseMapper.selectOne(queryWrapper);

        if (jshUser != null) {
            if (id!=null){
                if (id.equals(jshUser.getId())){
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    @Override
    public boolean checkIsUserNameExist(Long id,String userName) {
        QueryWrapper<JshUser> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(userName)) {
            queryWrapper.eq("username", userName);
        }
        JshUser jshUser = this.baseMapper.selectOne(queryWrapper);
        if (jshUser != null) {
            if (id!=null){
                if (id.equals(jshUser.getId())){
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean removeByUserId(Integer id) {
        //删除用户和角色的关联表
        QueryWrapper<JshUserRole> queryWrapper= new QueryWrapper<JshUserRole>().eq("jsh_user_id",id);
        jshUserRoleMapper.delete(queryWrapper);
        return removeById(id);
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean removeBatchByUserIds(Long[] ids) {
        jshUserRoleMapper.delete(new QueryWrapper<JshUserRole>().in("jsh_user_id", Arrays.asList(ids)));
        return removeBatchByIds(Arrays.asList(ids));
    }

    @Override
    public AjaxResult login(LoginBody loginBody) {
        Authentication authenticate;
        //Authentication 封装 登录用户信息
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginBody.getUsername(), loginBody.getPassword());
        try{
            // AuthenticationManager 用来做认证
            authenticate = authenticationManager.authenticate(token);
            SecurityContextHolder.getContext().setAuthentication(authenticate);
        }catch (AuthenticationException e){
            return AjaxResult.error("用户名或密码错误");
        }
        if(Objects.isNull(authenticate)){
            return AjaxResult.error("用户名密码错误");
        }
        LoginUser loginUser = (LoginUser)authenticate.getPrincipal();
        // 生成Token
        String jwt = JwtUtil.createJWT(loginUser.getJshUser().getId().toString());
        //将JWT保到Redis中
        redisCache.setCacheObject("login:"+loginUser.getJshUser().getId(),loginUser);
        return AjaxResult.success("登录成功").put("token",jwt);
    }

    @Override
    public Object logout() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser =(LoginUser) authentication.getPrincipal();
        if(Objects.isNull(loginUser)){
            return AjaxResult.error("未登录");
        }
        redisCache.deleteObject("login:"+loginUser.getJshUser().getId());
        return AjaxResult.success("退出成功");
    }

    @Transactional(rollbackFor = RuntimeException.class)
    @Override
    public boolean saveJshUser(JshUser jshUser) {
        jshUser.setUsername(jshUser.getLoginName());
        jshUser.setDeleteFlag("0");
        jshUser.setStatus(Byte.parseByte("0"));
        jshUser.setIsystem(Byte.parseByte("1"));
        jshUser.setIsmanager(Byte.parseByte("1"));
        jshUser.setPassword(passwordEncoder.encode(jshUser.getPassword()));
        boolean save = save(jshUser);
        //当前租户编号
        jshUser.setTenantId(jshUser.getId());
        updateById(jshUser);

        //添加用户和角色关系表
        JshUserRole jshUserRole = new JshUserRole(10L, jshUser.getId());
        jshUserRoleMapper.insert(jshUserRole);

        //添加租户表
        JshTenant jshTenant = new JshTenant();
        jshTenant.setTenantId(jshUser.getTenantId());
        jshTenant.setLoginName(jshUser.getLoginName());
        jshTenant.setUserNumLimit(2000);
        jshTenant.setType("0");
        jshTenant.setEnabled(true);
        jshTenant.setCreateTime(new Date());
        jshTenantService.save(jshTenant);
        return save;
    }

}




